package fag.core.geometry;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;


/**
 * Classe des rectangles 2D. Le rectangle est défini par son coin supérieur gauche, et 
 * par sa largeur et sa hauteur.
 * @author lumz
 */
public class Rectangle2D extends AbstractPolygon implements Cloneable, Serializable {

	private static final long serialVersionUID = -3298729680529615463L;
	
	private Vector2D location = new Vector2D(0, 0);
	private double width = 0;
	private double height = 0;
	
	/**
	 * Constructeur par défault.
	 * Le rectangle est positionné à la coordonnée 0, 0 et ses dimensions sont nulles.
	 */
	public Rectangle2D() {
	}
	
	/**
	 * Constructeur avec initialisation.
	 * @param x La coordonnée x du coin supérieur gauche du rectangle.
	 * @param y La coordonnée y du coin supérieur gauche du rectangle.
	 * @param width Largeur du rectangle. 
	 * @param height Hauteur du rectangle.
	 */
	public Rectangle2D(double x, double y, double width, double height) {
		set(x, y, width, height);
	}
	
	/**
	 * Clône ce rectangle.
	 * @return Un clône du rectangle.
	 */
	public Rectangle2D clone() {
		
		Rectangle2D clone = (Rectangle2D) super.clone();
		clone.location = location.clone();
		
		return clone;
	}
	
	@Override
	public boolean equals(Object other) {
		
		if(this == other)
			return true;
		
		if(!(other instanceof Rectangle2D))
			return false;
		
		final Rectangle2D rectangle = (Rectangle2D)(other);
		
		return location.equals(rectangle.location) && width == rectangle.width && height == rectangle.height;
	}
	
	@Override
	public Rectangle2D getBounds() {
		return new Rectangle2D(location.x, location.y, width, height);
	}
	
	/**
	 * Getter de la hauteur du rectangle.
	 * @return La hauteur du rectangle.
	 */
	public double getHeight() {
		return height;
	}
	
	/**
	 * Getter des coordonnées du coin supérieur gauche du rectangle.
	 * @return Les coordonnées du coin supérieur gauche du rectangle.
	 */
	public Vector2D getLocation() {
		return location.clone();
	}
	
	/**
	 * Réimplémentation de Hill.
	 * @return La liste des sommets du rectangle dans le sens trigonométrique.
	 */
	public List<Vector2D> getVertices() {
		
		List<Vector2D> vertices = new ArrayList<Vector2D>();
		
		vertices.add(location.clone());
		vertices.add(location.add(new Vector2D(0, height)));
		vertices.add(location.add(new Vector2D(width, height)));
		vertices.add(location.add(new Vector2D(width, 0)));
		
		return vertices;
	}
	
	/**
	 * Getter de la largeur du rectangle.
	 * @return La largeur du rectangle.
	 */
	public double getWidth() {
		return width;
	}
	
	/**
	 * Getter de la coordonnée x du coin supérieur gauche du rectangle.
	 * @return La valeur de la coordonnée x du coin supérieur gauche du rectangle.
	 */
	public double getX() {
		return location.x;
	}
	
	/**
	 * Getter de la coordonnée y du coin supérieur gauche du rectangle.
	 * @return La valeur de la coordonnée y du coin supérieur gauche du rectangle.
	 */
	public double getY() {
		return location.y;
	}
	
	/**
	 * Setter de la géométrie du rectangle.
	 * @param x Coordonnée x du coin supérieur gauche du rectangle.
	 * @param y Coordonnée y du coin supérieur gauche du rectangle.
	 * @param width Largeur du rectangle.
	 * @param height Hauteur du rectangle.
	 */
	public void set(double x, double y, double width, double height) {
		location.set(x, y);
		this.width = width;
		this.height = height;
	}
	
	/**
	 * Setter des coordonnées du coin supérieur gauche du rectangle.
	 * @param p Valeurs des coordonnées du nouveau coin supérieur gauche du rectangle.
	 */
	public void setLocation(Vector2D location) {
		this.location = location.clone();
	}
	
	/**
	 * Setter des coordonnées du coin supérieur gauche du rectangle.
	 * @param x Valeur de la coordonnée x du nouveau coin supérieur gauche du rectangle.
	 * @param y Valeur de la coordonnée y du nouveau coin supérieur gauche du rectangle.
	 */
	public void setLocation(double x, double y) {
		location.set(x, y);
	}
	
	@Override
	public String toString() {
		return new String() + "Rectangle2D(" + location.x + ", " + location.y + ", " + width + ", " + height + ")";
	}
}
